//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from "react";
import { Button, ConfigProvider, message, Space } from 'antd';
import zhCN from 'antd/lib/locale/zh_CN';
import { createRoot } from 'react-dom/client';
import 'moment/dist/locale/zh-cn';
import 'remirror/styles/all.css';
import '@/components/Editor/editor.less';
import '@/styles/global.less';
import { BrowserRouter, useLocation } from "react-router-dom";
import { appWindow } from "@tauri-apps/api/window";
import { CloseSquareOutlined, EditOutlined, FormatPainterOutlined, PushpinFilled, PushpinOutlined } from "@ant-design/icons";
import { get_memo, update_memo, type MemoInfo } from "@/api/user_memo";
import { get_session } from "@/api/user";
import { ReadOnlyEditor, useCommonEditor } from "@/components/Editor";
import { FILE_OWNER_TYPE_USER_MEMO } from "@/api/fs";
import { request } from "@/utils/request";
import type * as NoticeType from '@/api/notice_type';
import { listen } from '@tauri-apps/api/event';
import { observer, useLocalObservable } from "mobx-react";
import { runInAction } from "mobx";
import { report_error } from "@/api/client_cfg";

const Content = observer(() => {
    const location = useLocation();
    const urlParams = new URLSearchParams(location.search);
    const memoId = urlParams.get("id") ?? "";
    const fsId = urlParams.get("fsId") ?? "";

    const [memoInfo, setMemoInfo] = useState<MemoInfo | null>(null);
    const [onTop, setOnTop] = useState(true);

    const localStore = useLocalObservable(() => ({
        inEdit: false,
        setInEdit(val: boolean) {
            runInAction(() => {
                this.inEdit = val;
            });
        },
    }));

    const { editor, editorRef } = useCommonEditor({
        placeholder: "请输入内容",
        content: "",
        fsId: fsId,
        ownerType: FILE_OWNER_TYPE_USER_MEMO,
        ownerId: memoId,
        historyInToolbar: false,
        clipboardInToolbar: false,
        commonInToolbar: false,
        pubResInToolbar: false,
        hideToolbar: true,
    });

    const loadUserMemo = async () => {
        const sessionId = await get_session();
        const res = await request(get_memo({
            session_id: sessionId,
            memo_id: memoId,
        }));
        setMemoInfo(res.memo);
    };

    const onUpdate = async (newMemoId: string) => {

        if (newMemoId != memoId || localStore.inEdit) {
            return;
        }
        await loadUserMemo();
    };

    const updateUserMemo = async () => {
        if (memoInfo == null) {
            return;
        }
        const content = editorRef.current?.getContent() ?? { type: "doc" };
        const sessionId = await get_session();
        await request(update_memo({
            session_id: sessionId,
            memo_id: memoId,
            basic_info: {
                ...memoInfo.basic_info,
                content: JSON.stringify(content),
            },
        }));
        localStore.setInEdit(false);
        await loadUserMemo();
    };

    const updateBgColor = async (bgColor: string) => {
        if (memoInfo == null) {
            return;
        }
        const sessionId = await get_session();
        await request(update_memo({
            session_id: sessionId,
            memo_id: memoId,
            basic_info: {
                ...memoInfo.basic_info,
                bg_color: bgColor,
            },
        }));
        await loadUserMemo();
    };

    const hexToRGB = (hex: string, alpha: number) => {
        const r = parseInt(hex.slice(1, 3), 16),
            g = parseInt(hex.slice(3, 5), 16),
            b = parseInt(hex.slice(5, 7), 16);

        if (alpha) {
            return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
        } else {
            return "rgb(" + r + ", " + g + ", " + b + ")";
        }
    }

    useEffect(() => {
        loadUserMemo();
    }, [memoId]);

    useEffect(() => {
        if (memoInfo == null || editorRef.current == null || !localStore.inEdit) {
            return;
        }
        editorRef.current.setContent(memoInfo.basic_info.content);
    }, [memoInfo, editorRef, editorRef.current, localStore.inEdit]);

    useEffect(() => {
        const unListenFn = listen<NoticeType.AllNotice>("notice", ev => {
            const notice = ev.payload;
            if (notice.ClientNotice?.UpdateUserMemoNotice != undefined) {
                onUpdate(notice.ClientNotice.UpdateUserMemoNotice.memoId);
            }
        });
        return () => {
            unListenFn.then((unListen) => unListen());
        };
    }, []);

    return (
        <div style={{
            backgroundColor: hexToRGB(memoInfo?.basic_info.bg_color ?? "#8bc34a", 0.8),
            width: "100wh",
            height: "100vh",
            overflowY: "scroll",
            borderRadius: "10px",
            cursor: "move"
        }} data-tauri-drag-region>
            <div style={{ position: "relative", height: "30px", paddingTop: "10px" }} data-tauri-drag-region>
                <Space style={{ position: "absolute", right: "20px" }}>
                    {localStore.inEdit == false && (
                        <>
                            <Button type="link" icon={<EditOutlined style={{ fontSize: "24px" }} title="编辑"/>} onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                localStore.setInEdit(true);
                            }} />
                            <Button type="text" icon={onTop ? <PushpinFilled style={{ fontSize: "24px" }} title='取消置顶' /> : <PushpinOutlined style={{ fontSize: "24px" }} title='置顶' />} onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                if(onTop){
                                    appWindow.setAlwaysOnTop(false).then(()=>setOnTop(false));
                                }else{
                                    appWindow.setAlwaysOnTop(true).then(()=>setOnTop(true));
                                }
                            }} />
                            <Button type="text" icon={<FormatPainterOutlined style={{ fontSize: "24px" }} title="更新背景颜色"/>} onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                const colorList = ["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#795548", "#607d8b"];
                                const index = Math.floor(Math.random() * colorList.length);
                                updateBgColor(colorList[index]);
                            }} />
                            <Button type="text" icon={<CloseSquareOutlined style={{ fontSize: "24px" }} title="关闭"/>} onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                appWindow.close();
                            }} />
                        </>
                    )}
                    {localStore.inEdit == true && (
                        <>
                            <Button type="default" size="small" onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                localStore.setInEdit(false);
                            }}>取消</Button>
                            <Button type="primary" size="small" onClick={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                updateUserMemo();
                            }}>保存</Button>
                        </>
                    )}

                </Space>
            </div>
            {memoInfo != null && (
                <div className="_userMemoContext" style={{ padding: localStore.inEdit ? undefined : "10px 10px" }}>
                    {localStore.inEdit == false && (
                        <ReadOnlyEditor content={memoInfo.basic_info.content} />
                    )}
                    {localStore.inEdit == true && (
                        <>
                            {editor}
                        </>
                    )}
                </div>
            )}
        </div>
    );
});

const App = () => {
    return (
        <ConfigProvider locale={zhCN}>
            <BrowserRouter>
                <Content />
            </BrowserRouter>
        </ConfigProvider>
    );
}

const root = createRoot(document.getElementById('root')!);
root.render(<App />);

window.addEventListener('unhandledrejection', function (event) {
    // 防止默认处理（例如将错误输出到控制台）
    event.preventDefault();
    if (`${event.reason}`.includes("error trying to connect")) {
      return;
    }
    message.error(event?.reason);
    // console.log(event);
    try {
      report_error({
        err_data: `${event?.reason}`,
      });
    } catch (e) {
      console.log(e);
    }
  });